// UsesStatTable.cpp : stores the variables used in each statement.
// Author: Achyut P Balaji
//

#include"UsesStatTable.h"

/*Description: Private Constructor if class UsesStatTable.*/
UsesStatTable::UsesStatTable(int noOfStmts, int noOfVars) {
	noofstmts = noOfStmts;
	noofvars = noOfVars;
	usesTable = new int*[noofstmts];
	for(int i=0;i<noofstmts;i++) {
		usesTable[i] = new int[noofvars];
	}
	for(int i=0;i<noofstmts;i++) 
		for(int j=0;j<noofvars;j++)
			usesTable[i][j] = 0;
	initialised = false;
}

UsesStatTable::~UsesStatTable() {
	for(int i=0; i< noofstmts;i++) {
		delete[] usesTable[i];
	}
	delete[] usesTable;
}

UsesStatTable* UsesStatTable::obj = NULL;

/*Description: This function is used to get the object of the class UsesStatTable.
Implements the Singleton Design Pattern and prevents decleration of anymore objects of this class. */
UsesStatTable* UsesStatTable::getInstance(){
		if(!obj) 
			obj = new UsesStatTable(0,0);
		return obj;
}

/*Description: This function is used to reinitialise the object of the class UsesStatTable.
Implements the Singleton Design Pattern and prevents decleration of anymore objects of this class. */
UsesStatTable* UsesStatTable::getFirstInstance(int noOfStmts, int noOfVars){
		obj = new UsesStatTable(noOfStmts,noOfVars);
		return obj;
}

BOOLEAN UsesStatTable::addEntry(STATEMENT_INDEX n, VAR_LIST varUsed) {
	for(unsigned int i=0;i<varUsed.size();i++) {
		usesTable[n-1][varUsed.at(i)] = 1;
	}

	return true;
}

BOOLEAN UsesStatTable::isUsed(STATEMENT_INDEX n, VAR_INDEX ind) {
	if(initialised == true) {
		if(usesTable[n-1][ind] == 1) {
			return true;
		}
	}
	else {
		if(usesTable[noofstmts-n][ind] == 1) {
			return true;
		}
	}
	return false;
}

VAR_LIST* UsesStatTable::getVarUsed(STATEMENT_INDEX n) {
	emptyTempVector();
	if(initialised == true) {
		for(int i=0;i<noofvars;i++) {
			if(usesTable[n-1][i] == 1) {
				tempVector.push_back(i);
			}
		}
	}
	else {
		for(int i=0;i<noofvars;i++) {
			if(usesTable[noofstmts-n][i] == 1) {
				tempVector.push_back(i);
			}
		}
	}
	return &tempVector;
}

STMT_LIST* UsesStatTable::getStmtUsedIn(VAR_INDEX v) {
	emptyTempVector();
	if(initialised == true) {
		for(int i=0;i<noofstmts;i++) {
			if(usesTable[i][v] == 1) {
				tempVector.push_back(i+1);
			}
		}
	}
	else {
		for(int i=0;i<noofstmts;i++) {
			if(usesTable[i][v] == 1) {
				tempVector.push_back(i+1);
			}
		}
	}
	return &tempVector;
}

void UsesStatTable::initialise() {
	initialised = true;
}

void UsesStatTable::emptyTempVector() {
	int temp = tempVector.size();
	for(int i=0;i<temp;i++) {
		tempVector.pop_back();
	}
}